using System;
using System.Data;

namespace SharpObjects.Data
{

	public class DbRow
	{
		protected DataRow dataRow;

		public DbRow(DataRow dataRow)
		{
			this.dataRow = dataRow;
			this.strprop = new StringProperty(this);
			this.intprop = new IntegerProperty(this);
			this.longprop = new LongProperty(this);
			this.dblprop = new DoubleProperty(this);
			this.dtprop = new DateTimeProperty(this);
			this.boolprop = new BooleanProperty(this);
		}

		public DataRow Row { get { return dataRow; } }

		public bool GetBoolean(string columnName)
		{
			if (dataRow.IsNull(columnName))
			{
				throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
			}
			string stringValue = dataRow[columnName].ToString().Trim();
			
			if(stringValue == "0")
			{
				return false;
			}
			else if(stringValue == "1")
			{
				return true;
			}
			else if(stringValue.ToUpper() == "Y")
			{
				return true;
			}
			else if(stringValue.ToUpper() == "N")
			{
				return false;
			}
			else if(stringValue.ToUpper() == "T")
			{
				return true;
			}
			else if(stringValue.ToUpper() == "F")
			{
				return false;
			}
			else
			{
				return Convert.ToBoolean(stringValue);
			}
		}
 
		public bool GetBoolean(string columnName, bool defaultValue)
		{
			if (dataRow.IsNull(columnName))
			{
				return defaultValue;
			}
			return this.GetBoolean(columnName);
		}

		protected BooleanProperty boolprop;
		public BooleanProperty BooleanValue{ get { return this.boolprop; } }

		public DateTime GetDateTime(string columnName)
		{
			if (dataRow.IsNull(columnName))
			{
				throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
			}
			return (DateTime) dataRow[columnName];
		}
 
		public DateTime GetDateTime(string columnName, DateTime defaultValue)
		{
			if (dataRow.IsNull(columnName))
			{
				return defaultValue;
			}
			return this.GetDateTime(columnName);
		}

		protected DateTimeProperty dtprop; 
		public DateTimeProperty DateTimeValue { get { return this.dtprop; } }
 
		public double GetDouble(string columnName)
		{
			if (dataRow.IsNull(columnName))
			{
				throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
			}
			string sValue = dataRow[columnName].ToString().Trim();
			return Convert.ToDouble(sValue);
		}
 
		public double GetDouble(string columnName, double defaultValue)
		{
			if (dataRow.IsNull(columnName))
			{
				return defaultValue;
			}
			return this.GetDouble(columnName);
		}

		protected DoubleProperty dblprop;
		public DoubleProperty DoubleValue { get { return this.dblprop; } }

        public decimal GetDecimal(string columnName)
        {
            if (dataRow.IsNull(columnName))
            {
                throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
            }
            string sValue = dataRow[columnName].ToString().Trim();
            return Convert.ToDecimal(sValue);
        }

        public decimal GetDecimal(string columnName, decimal defaultValue)
        {
            if (dataRow.IsNull(columnName))
            {
                return defaultValue;
            }
            return this.GetDecimal(columnName);
        }

        protected DecimalProperty decprop;
        public DecimalProperty DecimalValue { get { return this.decprop; } }

        public int GetInteger(string columnName)
		{
			if (dataRow.IsNull(columnName))
			{
				throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
			}
			string sValue = dataRow[columnName].ToString().Trim();
			return Convert.ToInt32(sValue);
		}
 
		public int GetInteger(string columnName, int defaultValue)
		{
			if (dataRow.IsNull(columnName))
			{
				return defaultValue;
			}
			return this.GetInteger(columnName);
		}

		protected IntegerProperty intprop;
		public IntegerProperty IntegerValue { get { return this.intprop; } }
 
		public long GetLong(string columnName)
		{
			if (dataRow.IsNull(columnName))
			{
				throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
			}
			string sValue = dataRow[columnName].ToString().Trim();
			return Convert.ToInt64(sValue);
		}
 
		public long GetLong(string columnName, long defaultValue)
		{
			if (dataRow.IsNull(columnName))
			{
				return defaultValue;
			}
			return this.GetLong(columnName);
		}

		protected LongProperty longprop;
		public LongProperty LongValue { get { return this.longprop; } }
 
		public string GetString(string columnName)
		{
			if (dataRow.IsNull(columnName))
			{
				throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
			}
			return dataRow[columnName].ToString();
		}
 
		public string GetString(string columnName, string defaultValue)
		{
			if (dataRow.IsNull(columnName))
			{
				return defaultValue;
			}
			return this.GetString(columnName);
		}
 
		protected StringProperty strprop;
		public StringProperty StringValue { get { return this.strprop; } }

		public class StringProperty
		{
			protected DbRow row;
			public StringProperty(DbRow row) { this.row = row; }

			public string this[string columnName] { get{ return this.row.GetString(columnName); } }
			public string this[string columnName, string defaultValue] { get { return this.row.GetString(columnName, defaultValue); } }
		}

		public class IntegerProperty
		{
			protected DbRow row;
			public IntegerProperty(DbRow row) { this.row = row; }

			public int this[string columnName] { get{ return this.row.GetInteger(columnName); } }
			public int this[string columnName, int defaultValue] { get { return this.row.GetInteger(columnName, defaultValue); } }
		}

		public class LongProperty
		{
			protected DbRow row;
			public LongProperty(DbRow row) { this.row = row; }

			public long this[string columnName] { get{ return this.row.GetLong(columnName); } }
			public long this[string columnName, long defaultValue] { get { return this.row.GetLong(columnName, defaultValue); } }
		}

		public class DoubleProperty
		{
			protected DbRow row;
			public DoubleProperty(DbRow row) { this.row = row; }

			public double this[string columnName] { get{ return this.row.GetDouble(columnName); } }
			public double this[string columnName, double defaultValue] { get { return this.row.GetDouble(columnName, defaultValue); } }
		}

        public class DecimalProperty
        {
            protected DbRow row;
            public DecimalProperty(DbRow row) { this.row = row; }

            public decimal this[string columnName] { get { return this.row.GetDecimal(columnName); } }
            public decimal this[string columnName, decimal defaultValue] { get { return this.row.GetDecimal(columnName, defaultValue); } }
        }

        public class DateTimeProperty
		{
			protected DbRow row;
			public DateTimeProperty(DbRow row) { this.row = row; }

			public DateTime this[string columnName] { get{ return this.row.GetDateTime(columnName); } }
			public DateTime this[string columnName, DateTime defaultValue] { get { return this.row.GetDateTime(columnName, defaultValue); } }
		}

		public class BooleanProperty
		{
			protected DbRow row;
			public BooleanProperty(DbRow row) { this.row = row; }

			public bool this[string columnName] { get{ return this.row.GetBoolean(columnName); } }
			public bool this[string columnName, bool defaultValue] { get { return this.row.GetBoolean(columnName, defaultValue); } }
		}

	}




}
